package com.dream.model.order;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.Type;

import com.dream.model.app.AppCodeItem;
import com.dream.model.base.AppUserModelBase;
import com.dream.model.master.Product;
import com.dream.utils.date.DateParseUtils;
import com.dream.vo.api.ApiOrder;
import com.dream.vo.api.ApiOrderDetail;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Entity
@Table(name="t_order")
public class OnlineOrder extends AppUserModelBase implements Serializable {


	/**
	 * 
	 */
	private static final long serialVersionUID = -469717846776869580L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id ;
	
	@Column(name="code")
	private String code;
	
	@Column(name="status")
	@Enumerated(EnumType.STRING)
	private OrderStatus status;
	
	@Column(name="product_id")
	private Long productId;
	
	@Column(name="type")
	private Long type;
	
	@Column(name="urgent_level")
	private Long urgentLevel;
	
	@Column(name="mandatory_level")
	private Long mandatoryLevel;	

	@Column(name="order_date")
	@Temporal(TemporalType.TIMESTAMP)
	private Date orderDate;
	
	@Column(name="order_user")
	private String orderUser;
	
	@Column(name="order_mobile")
	private String orderMobile;
	
	@Column(name="hitch_type")
	private Long hitchType; 
	
	@Column(name="hitch_comments")
	private String hitchComments;
	
	@Column(name="comments")
	private String comments;
	
	@Column(name="dispatchor")
	private String dispatchor;
	
	@Column(name="dispatch_date")
	@Temporal(TemporalType.TIMESTAMP)
	private Date dispatchDate;
	
	@Column(name="handle_shop")
	private String handleShop; 
	
	@Column(name="accept_user")
	private String acceptUser;	

	@Column(name="accept_date")
	@Temporal(TemporalType.TIMESTAMP)
	private Date accpetDate;
	
	@Column(name="deleted")
	@Type(type = "org.hibernate.type.NumericBooleanType")
	private Boolean deleted = false;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="product_id",updatable=false,insertable=false)
	private OrderCustomerProduct orderProduct;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="type",updatable=false,insertable=false)
	private AppCodeItem typeObj;
	
	@Column(name="repair_cost")
	private Float repairCost;
	
	@Column(name="service_type")
	private Long serviceType;
	
	@Column(name="service_cost")
	private Float serviceCost;
	
	@Column(name="distance")
	private Long distance;
	
	@Column(name="travel_cost")
	private Float travelCost;
	
	@Column(name="visit_cost")
	private Float visitCost;
	
	@Column(name="other_cost")
	private Float otherCost;
	
	@Column(name="mandatory_cost")
	private Float mandatoryCost;
	
	@Column(name="satisfaction")
	private Long satisfaction;
	
	@Column(name="part_cost")
	private Float partCost;
	
	@Column(name="repair_type")
	private Long repairType;
	
	@Column(name="repair_date")
	@Temporal(TemporalType.TIMESTAMP)
	private Date repairDate;
	
	@Column(name="repair_user")
	private String repairUser;
	
	@Column(name="repair_comment")
	private String repairComments;
	
	
	public Float getMandatoryCost() {
		return mandatoryCost;
	}

	public void setMandatoryCost(Float mandatoryCost) {
		this.mandatoryCost = mandatoryCost;
	}

	public String getRepairUser() {
		return repairUser;
	}

	public void setRepairUser(String repairUser) {
		this.repairUser = repairUser;
	}

	public Float getRepairCost() {
		return repairCost;
	}

	public void setRepairCost(Float repairCost) {
		this.repairCost = repairCost;
	}

	public Long getServiceType() {
		return serviceType;
	}

	public void setServiceType(Long serviceType) {
		this.serviceType = serviceType;
	}

	public Float getServiceCost() {
		return serviceCost;
	}

	public void setServiceCost(Float serviceCost) {
		this.serviceCost = serviceCost;
	}

	public Long getDistance() {
		return distance;
	}

	public void setDistance(Long distance) {
		this.distance = distance;
	}

	public Float getTravelCost() {
		return travelCost;
	}

	public void setTravelCost(Float travelCost) {
		this.travelCost = travelCost;
	}

	public Float getVisitCost() {
		return visitCost;
	}

	public void setVisitCost(Float visitCost) {
		this.visitCost = visitCost;
	}

	public Float getOtherCost() {
		return otherCost;
	}

	public void setOtherCost(Float otherCost) {
		this.otherCost = otherCost;
	}

	public Long getSatisfaction() {
		return satisfaction;
	}

	public void setSatisfaction(Long satisfaction) {
		this.satisfaction = satisfaction;
	}

	public Float getPartCost() {
		return partCost;
	}

	public void setPartCost(Float partCost) {
		this.partCost = partCost;
	}

	public Long getRepairType() {
		return repairType;
	}

	public void setRepairType(Long repairType) {
		this.repairType = repairType;
	}

	public Date getRepairDate() {
		return repairDate;
	}

	public void setRepairDate(Date repairDate) {
		this.repairDate = repairDate;
	}

	public String getRepairComments() {
		return repairComments;
	}

	public void setRepairComments(String repairComments) {
		this.repairComments = repairComments;
	}

	public String getOrderUser() {
		return orderUser;
	}

	public void setOrderUser(String orderUser) {
		this.orderUser = orderUser;
	}

	public String getOrderMobile() {
		return orderMobile;
	}

	public void setOrderMobile(String orderMobile) {
		this.orderMobile = orderMobile;
	}

	public AppCodeItem getTypeObj() {
		return typeObj;
	}

	public void setTypeObj(AppCodeItem typeObj) {
		this.typeObj = typeObj;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	
	public OrderCustomerProduct getOrderProduct() {
		return orderProduct;
	}

	public void setOrderProduct(OrderCustomerProduct orderProduct) {
		this.orderProduct = orderProduct;
	}

	public String getDispatchor() {
		return dispatchor;
	}

	public void setDispatchor(String dispatchor) {
		this.dispatchor = dispatchor;
	}

	public Date getDispatchDate() {
		return dispatchDate;
	}

	public void setDispatchDate(Date dispatchDate) {
		this.dispatchDate = dispatchDate;
	}

	public String getHandleShop() {
		return handleShop;
	}

	public void setHandleShop(String handleShop) {
		this.handleShop = handleShop;
	}

	public String getAcceptUser() {
		return acceptUser;
	}

	public void setAcceptUser(String acceptUser) {
		this.acceptUser = acceptUser;
	}

	public Date getAccpetDate() {
		return accpetDate;
	}

	public void setAccpetDate(Date accpetDate) {
		this.accpetDate = accpetDate;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getProductId() {
		return productId;
	}

	public void setProductId(Long productId) {
		this.productId = productId;
	}

	public Long getType() {
		return type;
	}

	public void setType(Long type) {
		this.type = type;
	}

	public Long getUrgentLevel() {
		return urgentLevel;
	}

	public void setUrgentLevel(Long urgentLevel) {
		this.urgentLevel = urgentLevel;
	}

	public Long getMandatoryLevel() {
		return mandatoryLevel;
	}

	public void setMandatoryLevel(Long mandatoryLevel) {
		this.mandatoryLevel = mandatoryLevel;
	}

	public Date getOrderDate() {
		return orderDate;
	}

	public void setOrderDate(Date orderDate) {
		this.orderDate = orderDate;
	}

	public Long getHitchType() {
		return hitchType;
	}

	public void setHitchType(Long hitchType) {
		this.hitchType = hitchType;
	}

	public String getHitchComments() {
		return hitchComments;
	}

	public void setHitchComments(String hitchComments) {
		this.hitchComments = hitchComments;
	}

	public Boolean getDeleted() {
		return deleted;
	}

	public void setDeleted(Boolean deleted) {
		this.deleted = deleted;
	}

	public OrderStatus getStatus() {
		return status;
	}

	public void setStatus(OrderStatus status) {
		this.status = status;
	}
	
	
	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		OnlineOrder other = (OnlineOrder) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	public static enum OrderStatus{ 
		order_submit,order_dispatch,order_accept,order_fixed,order_finish;
		private static final Map<String,OrderStatus> map = Maps.newConcurrentMap();
		  private static final List<String> li = Lists.newArrayList();
		  static{
			  for(OrderStatus item :values()){
				  map.put(item.name(), item);
				  li.add(item.name());
			  }
		  }
		 
		  public static List<String> getTypes(){
			  return li;
		  }
		  
		  public static OrderStatus getInstance(String name){
			  if(StringUtils.isBlank(name)) return null;
			  return map.get(name);
		  }
	}
	
	public ApiOrder toApiOrder(){
		
		ApiOrder order = new ApiOrder();
		order.setId(id);
		order.setCode(code);
		order.setCustomer(orderProduct.getCustomer().getName());
		order.setDate(DateParseUtils.format(this.getOrderDate(), "yy-MM-dd"));
		order.setPhone(orderMobile);
		return order;
	}
	
	public ApiOrderDetail toApiOrderDetail(){
		
		ApiOrderDetail detail = new ApiOrderDetail();
		
		detail.setId(id);
		
		OrderCustomer customer = orderProduct.getCustomer();
		detail.setCusFirstOrg(customer.getFirstOrg().getName());
		detail.setCusAddress(customer.getAddress());
		detail.setCusMobile(customer.getMobile());
		detail.setCusName(customer.getName());
		detail.setCusPhone(customer.getPhone());
		detail.setCusSecondOrg(customer.getSecondOrg().getName());
		detail.setCusType(customer.getType().toString());
		
		Product product = orderProduct.getProduct();
		detail.setProBarcode(orderProduct.getBarCode());
		detail.setProFirstCat(product.getFirstCat().getName());
		detail.setProMandatoryNo(orderProduct.getMandatoryNo());
		detail.setProName(product.getName());
		detail.setProPurchaseDate(DateParseUtils.formatShort(orderProduct.getPurchaseDate()));
		detail.setProPurchasePrice(orderProduct.getPurchasePrice().toString());
		detail.setProRecepitNo(orderProduct.getRecepitNo());
		detail.setProSalesContact(orderProduct.getSalesContact());
		detail.setProSalesShop(orderProduct.getSalesContact());
		detail.setProSecondCat(product.getSecondCat().getName());
		
		detail.setProFirstCatCode(product.getFirstCat().getId().toString());
		detail.setProSecondCatCode(product.getSecondCat().getId().toString());
		
		return detail;
	}
}
